package com.authine.cloudpivot.ext.service.impl;

import com.authine.cloudpivot.ext.constants.AppConst;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.constants.ServiceUrlConst;
import com.authine.cloudpivot.ext.dto.system.OutApiClientDto;
import com.authine.cloudpivot.ext.enums.order.OrderSyncEventTypeEnum;
import com.authine.cloudpivot.ext.model.bosi.BsscOrderDeliverGoodsModel;
import com.authine.cloudpivot.ext.model.bosi.OrderAcceptModel;
import com.authine.cloudpivot.ext.model.bosi.OrderGoodsDeliverModel;
import com.authine.cloudpivot.ext.model.order.OrderRemoteSyncEventParam;
import com.authine.cloudpivot.ext.service.OrderPunchoutService;
import com.authine.cloudpivot.ext.utils.BigDecimalUtils;
import com.authine.cloudpivot.ext.utils.HttpClients;
import com.authine.cloudpivot.ext.utils.JdbcTemplateUtils;
import com.authine.cloudpivot.ext.utils.RegexUtils;
import com.authine.cloudpivot.ext.utils.system.OutApiClientApiUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 订单事件调用punchout
 */
@Slf4j
public class OrderPunchoutServiceImpl implements OrderPunchoutService {

    @Override
    public void push(OrderRemoteSyncEventParam param) {
        //下单信息
        if(param.getType().equals(OrderSyncEventTypeEnum.OrderTaking)){
            this.pushOrderTaking(param.getOrderVendorIds());
        }
        //发货信息
        if(param.getType().equals(OrderSyncEventTypeEnum.SaveTransport)){
            this.pushSaveTransport(param.getTraceIds());
        }

    }

    /**
     * 请求punchout推送下单信息
     * @param orderVendorIds
     */
    private void pushOrderTaking(List<String> orderVendorIds) {

        if (CollectionUtils.isEmpty(orderVendorIds)) {
            log.warn("接单推送数据：参数不能为空");
        }
        List<Map<String, Object>> vendorOrderList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_VENDOR).selectField("*")
                .in("id", StringUtils.join(orderVendorIds, ",")).queryForList();

        if (CollectionUtils.isEmpty(vendorOrderList)) {
            log.warn("接单推送数据：根据供应商订单ID未查询到供应商订单数据");
        }

        List<OrderAcceptModel> pushOrderTakingList = new ArrayList<>();
        vendorOrderList.stream().map(t->t.get("order_customer_id")).distinct().forEach(orderCustomerId -> {
            if (null == orderCustomerId) {
                return;
            }

            Map<String, Object> customerOrder = JdbcTemplateUtils.builder(ModelConst.T_ORDER_CUSTOMER).selectField("client_order_id as clientOrderId, client_id as clientId")
                    .eq("id", orderCustomerId).queryForMap();
            if (null == customerOrder) {
                log.warn("接单推送数据：未查询到客户订单ID{}数据", orderCustomerId);
                return;
            }

            //验证是否推送
            if (!this.verifyIfPush((String) customerOrder.get("client_id"))) {
                return;
            }

            pushOrderTakingList.add(OrderAcceptModel.builder()
                    .orderNo((String) customerOrder.get("client_id"))
                    .mallOrderNo(orderCustomerId.toString())
                    .build());
        });

        if (CollectionUtils.isNotEmpty(pushOrderTakingList)) {
            String url = HttpClients.getUrl(AppConst.COMMODITYMATERIALS, ServiceUrlConst.ORDER_ACCEPT_URL);
            HttpClients.execute(url, pushOrderTakingList);
        }
    }

    /**
     * 请求punchout推送发货信息
     * @param traceIds
     */
    private void pushSaveTransport(List<String> traceIds) {

        if (CollectionUtils.isEmpty(traceIds)) {
            log.warn("发货推送数据：参数不能为空");
        }

        List<Map<String, Object>> transportList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_TRACE).selectField("id as id, order_customer_goods_id as objId, num as num, logistics as logistics, waybill as waybill")
                .in("id", StringUtils.join(traceIds, ",")).queryForList();
        if (org.springframework.util.CollectionUtils.isEmpty(transportList)) {
            throw new RuntimeException("根据发货记录ID未查询到发货记录数据");
        }

        String orderCustomerGoodsIds = transportList.stream().map(t -> t.get("objId").toString()).collect(Collectors.joining(","));
        List<Map<String, Object>> orderGoodsList = JdbcTemplateUtils.builder(ModelConst.T_ORDER_TRACE).selectField("id as id, goods_id as goodsId")
                .in("id", orderCustomerGoodsIds).queryForList();
        if (CollectionUtils.isEmpty(orderGoodsList)) {
            log.warn("发货推送数据：未查询到订单商品ID{}数据", orderCustomerGoodsIds);
            return;
        }

        List<BsscOrderDeliverGoodsModel> orderGoodsDeliverList = new ArrayList<>();
        orderGoodsList.stream().collect(Collectors.groupingBy(t->t.get("goodsId"))).forEach((goodsId, values) -> {
            List<String> orderGoodsIds = values.stream().map(t->(String)t.get("id")).collect(Collectors.toList());
            List<Map<String, Object>> traceList = transportList.stream().filter(t -> orderGoodsIds.contains(t.get("objId"))).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(traceList)) {
                return;
            }

            BigDecimal quantity = BigDecimal.ZERO;
            for (Map<String, Object> trace : traceList) {
                quantity = BigDecimalUtils.add(trace.get("num"), quantity);
            }
            BsscOrderDeliverGoodsModel deliverGoods = BsscOrderDeliverGoodsModel.builder()
                    .goodsId(goodsId.toString())
                    .num(quantity)
                    .build();
            orderGoodsDeliverList.add(deliverGoods);
        });

        String sql = "select customer.client_order_id as clientOrderId,customer.client_id as clientId from i_ordercenter_t_order_customer_goods goods " +
                "left join i_ordercenter_t_order_vendor vendor on vendor.id=goods.vendor_order_id " +
                "left join i_ordercenter_t_order_customer customer on customer.id=vendor.customer_order_id " +
                "where goods.id=" + transportList.get(0).get("objId");
        List<Map<String,Object>> customerOrders = JdbcTemplateUtils.queryForList(sql, new HashMap<>());
        if (CollectionUtils.isEmpty(customerOrders)) {
            log.warn("发货推送数据：未查询到订单商品ID{}对应的客户订单数据", transportList.get(0).get("objId"));
            return;
        }

        OrderGoodsDeliverModel model = OrderGoodsDeliverModel.builder()
                .orderNo((String) customerOrders.get(0).get("client_order_id"))
                .deliveryType("1")
                .expressCode(transportList.stream().map(t->(String) t.get("waybill")).distinct().collect(Collectors.joining(",")))
                .expressCompanyName((String) transportList.get(0).get("logistics"))
                .orderDeliverGoods(orderGoodsDeliverList)
                .build();

        if (this.verifyIfPush((String) customerOrders.get(0).get("client_id"))) {
            String url = HttpClients.getUrl(AppConst.COMMODITYMATERIALS, ServiceUrlConst.ORDER_GOODS_DELIVER_URL);
            HttpClients.execute(url, model);
        }
    }

    /**
     * 验证是不是冀中能源的订单
     * @param orderCustomerId
     * @return
     */
    private boolean verifyIfPush(String orderCustomerId) {
        OutApiClientDto punchoutBssc = OutApiClientApiUtils.getByGomroUsername("punchout_bssc");
        // 获取客户端数据
        String clientId = punchoutBssc.getClient_id();
        log.info("验证client_id:{}", clientId);
        if (RegexUtils.notNull(orderCustomerId) && orderCustomerId.equals(clientId)) {
            return true;
        }
        return false;
    }
}
